package controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import model.HandChain;
import model.Player;
import model.GameChain;
import model.timers.DoubleBlindCounter;



/**
 * This class is responsible for Game Logic(not any hand logic)
 * This includes 
 * * Keeping track of the deal button
 * * Keeping track of the blinds
 * 
 * @author phil
 *
 */
public class GameController{
	
	private DoubleBlindCounter blinds;
	protected GameChain gameChain; 
	
	public GameController(){
		gameChain = new GameChain();
		blinds = new DoubleBlindCounter(50, 5);		
	}
	
	/**
	 * The game is not over until there is only one player left.
	 * @return true is one player is left, false otherwise
	 */
	public boolean isGameOver(){
		System.out.println("Checking game over:" + gameChain.size() + " players left");
		if(gameChain.size() <= 1){
			return true;
		}
		return false;
	}
	
	
	private void giveButton(int seat){
		//Take button from who has it
		Collection<Player> players = this.gameChain.getPlayers();
		for(Player p : players){
			p.takeButton();
		}
		
		//Give it to player the specified player
		Player p = this.gameChain.getPlayer(seat);
		p.giveButton();
	}
	
	
	public void removePlayersWithoutChipsAndPassTheButton(){
		Set<Integer> seats = gameChain.getSeatNumbers();
		Iterator<Integer> i = seats.iterator();
		
		// Keep track of who has no chips left, remove them when finished iterating over the map
		ArrayList<Integer> playersToRemove = new ArrayList<Integer>();
		
		
		while(i.hasNext()){
			int seat = i.next();
			Player p = gameChain.getPlayer(seat);
			if(p.getChips() <= 0){				
				playersToRemove.add(seat);
				System.out.println("Removing player " + seat + " from the game");
			}
		}
		
		boolean hasButtonBeenPassed = false;
		for(Integer seat : playersToRemove){
			//if the player who has the button is to be removed, pass the button along
			if(gameChain.getPlayer(seat).hasButton()){
				gameChain.getNextPlayer();
				giveButton(gameChain.getActivePlayerSeat());
				hasButtonBeenPassed = true;
			}
			gameChain.remove(seat);
		}		
		if(!hasButtonBeenPassed){
			gameChain.getNextPlayer();
			giveButton(gameChain.getActivePlayerSeat());
		}
	}
	
	
	public void outputGameStats(int turnNumber){
		System.out.println("\n--------------------\nStarting Hand " + turnNumber);
		
		System.out.println("Button: Seat " + gameChain.getDealerPlayer().getSeat());
		
		Iterator it = gameChain.entrySet().iterator();
		while( it.hasNext() ){
			Map.Entry<Integer, Player> pairs = (Map.Entry<Integer, Player>)it.next();
			Player p = ((Player)pairs.getValue());
			System.out.print("Player in seat " + pairs.getKey() + ":");
			System.out.println("\n\tChips " + p.getChips() + "");
			if(p.hasButton()){
				System.out.println("\tHas Button");
			}
		}
		System.out.println("--------------------");
	}
	
	public void playGame(){
		int turnNumber = 1;		
		
		// Hand out the dealer button and set the active player
		Set<Integer> seats = gameChain.getSeatNumbers();
		Object[] seatsArray = seats.toArray();
		Arrays.sort(seatsArray);
		int dealerSeat = (int)seatsArray[0];
		gameChain.setDealerPlayer((int)seatsArray[0]);
		gameChain.initializeActivePlayer((int)seatsArray[0]);
		
		
		
		
		while(!isGameOver()){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			outputGameStats(turnNumber);
			
			//Game is not over, play another hand
			//Create the HandChain
			HandChain pChain = gameChain.getHandChain();
			HandController hChain = new HandController(pChain);
						
			//Play a hand
			hChain.playHand(blinds);
						
			// Remove any dead players
			removePlayersWithoutChipsAndPassTheButton();
						
			turnNumber++;
		}
		outputGameStats(turnNumber);
		System.out.println("Congratuations player in seat " + gameChain.getActivePlayerSeat() + " you win !");
	}
	
	public void insertPlayer(int seat, Player player){
		System.out.println("Player" + seat + " is attempting to join the game");
		gameChain.addPlayer(seat, player);	
	}
	
}
